package edu.gatech.bsbmule.model;

import java.awt.Color;
import java.util.ArrayList;
import java.util.List;


/**
 * This is a class that represents a player in the game. It contains 
 * a player's attributes, tiles and resources.
 * 
 * @author BSB
 * @version 1.0 10/5/2013
 * 
 */
public class Player {
	private String name;
	private Color color;
	private int race;
	private int money;
	private List<Tile> tiles;
	private Mule mule;
	private int food;
	private int energy;
	private int smithore;
	private int score;
	private boolean firstTimeFreeLand;
	
	public static final int RACE_FLAPPER = 0;
	public static final int RACE_HUMAN = 1;
	public static final int RACE_OTHERS = 2;

	public Player() {};
	
	/**
	 * Constructor
	 * 
	 * @param name
	 * @param color
	 * @param race
	 * @param money
	 * @param food
	 * @param energy
	 * @param smithore
	 */
	public Player(String name, Color color, int race, int money, int food,
			int energy, int smithore) {
		this.name = name;
		this.color = color;
		this.race = race;
		this.money = money;
		this.food = food;
		this.energy = energy;
		this.smithore = smithore;
		tiles = new ArrayList<Tile>();
		firstTimeFreeLand = true;
	}
	
	/**
	 * Gets name
	 * 
	 * @return name
	 */
	public String getName() {
		return name;
	}
	
	/**
	 * Gets color
	 * 
	 * @return color
	 */
	public Color getColor() {
		return color;
	}

	/**
	 * Gets energy amount
	 * 
	 * @return energy
	 */
	public int getEnergy() {
		return energy;
	}

	/**
	 * Gets food amount
	 * 
	 * @return food
	 */
	public int getFood() {
		return food;
	}

	/**
	 * Gets money amount
	 * 
	 * @return money
	 */
	public int getMoney() {
		return money;
	}
	
	/**
	 * Gets smithore amount
	 * 
	 * @return smithore
	 */
	public int getSmithore() {
		return smithore;
	}
	
	/**
	 * Increases money
	 * 
	 * @param int amount
	 */
	public void addMoney(int amount) {
		money += amount; 
	}
	
	/**
	 * Decreases money
	 * 
	 * @param int amount
	 */
	public void subtractMoney(int amount) {
		money -= amount; 
	}
	
	/**
	 * Increases food
	 * 
	 * @param int amount
	 */
	public void addFood(int amount) {
		food += amount;
	}
	
	/**
	 * Decreases food
	 * 
	 * @param int amount
	 */
	public void subtractFood(int amount) {
		food -= amount;
	}
	
	/**
	 * Increases energy
	 * 
	 * @param int amount
	 */
	public void addEnergy(int amount) {
		energy += amount;
	}
	
	/**
	 * Decreases energy
	 * 
	 * @param int amount
	 */
	public void subtractEnergy(int amount) {
		energy -= amount;
	}
	
	/**
	 * Increases smithore
	 * 
	 * @param int amount
	 */
	public void addSmithore(int amount) {
		smithore += amount;
	}

	/**
	 * Decreases smithore
	 * 
	 * @param int amount
	 */
	public void subtractSmithore(int amount) {
		smithore -= amount;
	}
	
	/**
	 * Gets list of tiles
	 * 
	 * @return tiles
	 */
	public List<Tile> getTiles() {
		return tiles;
	}
	
	/**
	 * Adds tile to player inventory
	 * 
	 * @param Tile tile
	 */
	public void addOwnedTile(Tile tile) {
		tiles.add(tile); 
	}
	
	/**
	 * Removes tile from player inventory
	 * 
	 * @param Tile tile
	 */
	public void removeTile(Tile tile) {
		tiles.remove(tile); 
	}
	
	/**
	 * Checks if player owns tile
	 * 
	 * @param Tile tile
	 * @return true if player owns tile
	 */
	public boolean isOwnedTile(Tile tile) {
		return tiles.contains(tile);
	}
	
	/**
	 * Calculate score. Score equals player money
	 */
	public void calcScore(){
		setScore(money);
	}
	
	/**
	 * Gets score
	 * 
	 * @return score
	 */
	public int getScore() {
		calcScore();
		return score;
	}
	
	/**
	 * Sets score
	 * 
	 * @param int score
	 */
	public void setScore(int score) {
		this.score = score;
	}
	
	/**
	 * Sets food
	 * 
	 * @param int food
	 */
	public void setFood(int food) {
		this.food = food;
	}
	
	/**
	 * Sets energy
	 * 
	 * @param int energy
	 */
	public void setEnergy(int energy) {
		this.energy = energy;
	}
	
	/**
	 * Sets smithore
	 * 
	 * @param int smithore
	 */
	public void setSmithore(int smithore) {
		this.smithore = smithore;
	}
	
	/**
	 * Gets mule
	 * 
	 * @return mule
	 */
	public Mule getMule() {
		return mule;
	}
	
	/**
	 * Sets mule
	 * 
	 * @param int type
	 */
	public void setMule(int type) {
		if (type == -1) {
			mule = null;
		} else
			mule = new Mule(type);
	}
	
	/**
	 * Gets if player can receive free land
	 * 
	 * @return true if can receive free land
	 */
	public boolean getFirstTimeFreeLand() {
		return firstTimeFreeLand;
	}
	
	/**
	 * Sets free land status
	 * 
	 * @param bool fffl
	 */
	public void setFirstTimeFreeLand(boolean fffl) {
		firstTimeFreeLand = fffl;
	}
	
	public boolean ownsTile(Tile t){
		for (Tile tile : this.tiles)
			if (tile.equals(t)) {
				return true;
			}
		return false;
	}
	
	public void production(){
		int i = this.getEnergy();
		int[] prod = new int[3]; // {food, energy, smithore} produced
		for (Tile t : tiles){
			if (t.isUsed() && i > 0){
				int[] arr = t.getProduct();
				for (int j = 0; j < prod.length; j++)
				{
					prod[j] += arr[j];
				}
			}
				
		}
		System.out.println("Produced : Food - "+ prod[0] +", Energy - "+ prod[1]+", Smithore - "+prod[2]);
		this.food += prod[0];
		this.energy += prod[1];
		this.smithore += prod[2];
	}
	
	/**
	 * String representation of player inventory
	 * 
	 * @return string
	 */
	public String getInventory() {
		return "Player Inventory: " + "\n"
				+ "-----------------------" + "\n"
				+ "Money: " + money + "\n"
				+ "Food: " + food + "\n"
				+ "Energy: " + energy + "\n"
				+ "Smithore: " + smithore +"\n"
				+ "Mules: " + mule;
	}
	
	/**
	 * String representation of player info
	 * 
	 * @return string
	 */
	public String toString() {
		String tilesInfo = "";
		for (Tile t : tiles) {
			tilesInfo += t.toString() + "\n";
		}
		return "Name: " + name
				+ " Color: " + color.getRGB()
				+ " Race: " + race
				+ " Money: " + money
				+ " Food: " + food 
				+ " Energy: " + energy
				+ "\nTiles owned\n" + tilesInfo;
	}
}